package cn.lenchu.data.h2.dao;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.lenchu.data.dao.GroupDao;
import cn.lenchu.data.dao.GroupStockDao;
import cn.lenchu.data.h2.converter.GroupConverter;
import cn.lenchu.data.h2.entity.GroupEntity;
import cn.lenchu.data.h2.repository.GroupRepository;
import cn.lenchu.data.model.Group;
import cn.lenchu.data.model.GroupStock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author lenchu
 */
@Service
public class GroupDaoImpl implements GroupDao {

    @Autowired
    private GroupRepository groupRepository;

    @Autowired
    private GroupStockDao groupStockDao;

    @Override
    public List<Group> listByUserId(Integer userId) {
        return groupRepository.findAllByUserId(userId)
            .stream()
            .map(GroupConverter::toGroup)
            .collect(Collectors.toList());
    }

    @Override
    public Group getById(Integer id, boolean withDetail) {
        Optional<GroupEntity> groupEntityOptional = groupRepository.findById(id);
        if (groupEntityOptional.isPresent()) {
            GroupEntity groupEntity = groupEntityOptional.get();
            Group group = GroupConverter.toGroup(groupEntity);
            if (withDetail && group.getId() != null) {
                // fill detail
                List<GroupStock> groupStockList = groupStockDao.listByGroupId(group.getId());
                group.setGroupStockList(groupStockList);
            }
            return group;
        }
        return null;
    }

    @Override
    public Group upsert(Group group) {
        GroupEntity groupEntity = Optional.ofNullable(group)
            .map(GroupConverter::toGroupEntity)
            .orElse(null);
        if (groupEntity != null) {
            if (groupEntity.getId() == null) {
                groupEntity.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
                groupEntity = groupRepository.saveAndFlush(groupEntity);
                return GroupConverter.toGroup(groupEntity);
            } else {
                Optional<GroupEntity> entityOptional = groupRepository.findById(groupEntity.getId());
                if (entityOptional.isPresent()) {
                    GroupEntity entity = entityOptional.get();
                    BeanUtil.copyProperties(groupEntity, entity, CopyOptions.create().ignoreNullValue().ignoreError());
                    entity = groupRepository.saveAndFlush(entity);
                    return GroupConverter.toGroup(entity);
                }
            }
        }
        return null;
    }

    @Override
    public Group deleteById(Integer id) {
        Optional<GroupEntity> groupEntityOptional = groupRepository.findById(id);
        if (groupEntityOptional.isPresent()) {
            GroupEntity groupEntity = groupEntityOptional.get();
            groupRepository.deleteById(id);
            return GroupConverter.toGroup(groupEntity);
        }
        return null;
    }
}
